package com.ezerg.async;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;

import static java.util.stream.Collectors.toList;

public class ParallelStreamTest {
    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        //System.out.println(findPrice("java8实战"));
        //System.out.println(findPrice2("java8实战"));
        //System.out.println(findPrice3("java8实战"));
        System.out.println(findPrice4("java8实战"));
        long duration = System.currentTimeMillis() - start;
        System.out.println("总消耗时间：" + duration + "毫秒");
    }

    private static List<Shop> shops = Arrays.asList(new Shop("亚马逊"),
            new Shop("淘宝"),
            new Shop("京东商城"),
            new Shop("天猫商城"));

    public static List<String> findPrice(String product) {
        return shops.parallelStream()
                .map(shop -> String.format("%s 的价格是 %.2f", shop.getName(), shop.getPrice(product)))
                .collect(toList());

    }

    //CompletableFuture的并行操作
    public static List<String> findPrice2(String product) {
        List<CompletableFuture<String>> priceFuture = shops.stream()
                .map(shop -> CompletableFuture.supplyAsync( // 使用异步的方式计算每种商品的价格
                        () -> shop.getName() + " 的价格是 " + shop.getPrice(product)))
                .collect(toList());
        return priceFuture.stream()
                .map(CompletableFuture::join) //join 操作等待所有异步操作的结果
                .collect(toList());
    }

    public static List<String> findPrice3(String product) {
        return shops.stream()
                .map(shop -> shop.getPrice2(product)) //获取原始报价
                .map(Quote::parse) //解析报价字符串
                .map(Discount::applyDiscount) //调用折扣服务应用报价折扣
                .collect(toList());
    }

    //使用CompletableFutures异步操作
    public static List<String> findPrice4(String product) {
        List<CompletableFuture<String>> priceFuture = shops.stream()
                .map(shop -> CompletableFuture.supplyAsync( // 异步获取价格
                        () -> shop.getPrice2(product)))
                .map(future -> future.thenApply(Quote::parse)) // 获取到价格后对价格解析
                .map(future -> future.thenCompose(quote -> CompletableFuture.supplyAsync( // 另一个异步任务构造异步应用报价
                        () -> Discount.applyDiscount(quote))))
                .collect(toList());

        return priceFuture.stream()
                .map(CompletableFuture::join) //join 操作和get操作有相同的含义，等待所有异步操作的结果。
                .collect(toList());
    }

}
